import pdb
import tornado.web
import tornado.ioloop
import tornado.httpserver
import tornado.options
import os,json
import datetime
import time
from queue import Queue
import base64
from io import BytesIO
from PIL import Image
import torch

from tornado import gen
from tornado.concurrent import Future
from tornado.web import RequestHandler
from tornado.options import define, options
from tornado.websocket import WebSocketHandler

l = []
RATE=0.2
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')

class IndexHandler(RequestHandler):
	
  @gen.coroutine
  def get(self):
    msg = self.get_argument("msg")
    for itm in l:
      itm.write_message(msg)
    
  def post(self):
    try:
      file_data = self.request.files
      fv = file_data.get('photo')
      f = BytesIO()
      f.write(fv[0].body)
      f_name=f'f_{int(time.time())}.jpg'
      somthings = self.save(f,f_name)
      for itm in l:
        try:
          itm.write_message({"fName":f_name,"someThing":somthings})
        except Exception as e:
          itm.close()
    except Exception as es:
      pass
    finally:
      self.redirect('/static/up.html')
  
  def save(self,f,n):
    im = Image.open(f)
    x,y=im.size
    if x>1000:
      im = im.resize((int(x*RATE), int(y*RATE)), Image.ANTIALIAS)
    origin_name=os.path.join(os.path.dirname(__file__),'statics',n)
    with open(origin_name,'wb') as imgf:
      im.save(imgf)
    result = model(origin_name)
    result.save(os.path.join(os.path.dirname(__file__),'statics/yolo5'))
    return list(map(lambda x:x.get('label'),result.crop()))
 # 继承tornado.websocket.WebSocketHandler,只处理WS协议的请求
class ChatHandler(WebSocketHandler):
   
  @gen.coroutine
  def open(self):
    l.append(self)
      
  def on_message(self, message):
    if message== "ping":
      self.write_message("pong")
    pass

  def on_close(self):
    l.remove(self)
    # self.write_message(u"[%s]-[%s] 断开链接" % (self.request.remote_ip, datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")))

  def check_origin(self, origin):
    return True  # 允许WebSocket的跨域请求

if __name__ == '__main__':
    tornado.options.parse_command_line()    #允许命令行启动程序

    app = tornado.web.Application([         #定义处理web请求的应用程序
            (r"/", IndexHandler),
            (r"/chat", ChatHandler),        # 处理WebSocket协议传输的数据
        ],
        websocket_ping_interval = 5,         # WebSocket ping探活包发送间隔秒数
        static_path = os.path.join(os.path.dirname(__file__), "statics"),           #配置应用程序前端所需静态文件目录
        template_path = os.path.join(os.path.dirname(__file__), "templates"),       #配置html文件路径
        xsrf_cookies=False,                                                          #,防止跨站请求攻击，在post请求中起效,
        debug = True                                                                #配置调试级别
        )
    http_server = tornado.httpserver.HTTPServer(app)                                #将应用处理逻辑 传递给HTTPServer 服务
    define("port", default=8000, type=int)                                          #设置一个监听地址
    http_server.listen(options.port)                                                #配置监听地址到 HTTPServe
    tornado.ioloop.IOLoop.current().start()                                         #启动应用
